﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SpeakupBackend
{
    /// <summary>
    /// In order to use these helpers, class must inmplement:
    /// IEquatable<T> and IComparable<T>.
    /// 
    /// Implement CompareTo(T);
    /// 
    /// From Equals(Object): call Equals(this as T);
    /// From Equals(T)     : call IEquatableEquals(this, other);
    /// From GetHashCode() : call GetHashCode(arg1, arg2, ... , arg3). 
    ///                      All arguments that were used in CompareTo implementation.
    /// From operator ==   : call OperatorEqual(left,right)
    /// From operator !=   : call !(left==right)
    /// </summary>
    static class ClassHelper
    {
        public static bool IEquatableEquals<T>(T _this, T other) where T : class, IComparable<T>
        {
            //if both referneces are the same
            if (Object.ReferenceEquals(_this, other))
            {
                return true;
            }

            //if 'other' is null
            if (Object.ReferenceEquals(null, other))
            {
                return false;
            }

            return _this.CompareTo(other) == 0;            
        }

        public static int GetHashCode(params Object[] args)
        {
            return GetHashCodeMult(373, args);
        }

        public static int GetHashCodeMult(int mult, params Object[] args)
        {
            int hashCode = 0;

            unchecked
            {
                foreach(Object o in args)
                {
                    hashCode += mult * o.GetHashCode();
                }
            }
            return hashCode;
        }

        public static bool OperatorEqual<T>(T left, T right) where T : IComparable<T>
        {
            //if both are null or samre references return true
            if (Object.ReferenceEquals(left, right))
            {
                return true;
            }

            //if only one of them is null, return false
            if (Object.ReferenceEquals(left, null) ||
                Object.ReferenceEquals(null, right))
            {
                return false;
            }

            return left.CompareTo(right) == 0;
        }

        public static bool OperatorNotEqual<T>(T left, T right) where T : IComparable<T>
        {
            return !OperatorEqual(left, right);
        }
    }
}
